package ase.eleitweg.server;

import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import ase.eleitweg.common.*;
import ase.eleitweg.common.fail.*;
import ase.eleitweg.server.db.*;

import java.rmi.*;

import org.apache.log4j.*;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

import com.google.inject.Inject;

public abstract class AbstractLoginController<SC extends ServerHandle>
		implements LoginInterface<SC> {
	
	protected Logger log = Logger.getLogger(this.getClass());

	protected abstract boolean isAuthorised(String username, String md5passwd, User u);

	protected abstract SC getSC() throws RemoteException;

	protected List<ClientHandle> clients;
	
	private XmlBeanFactory xbf;
	
	@Inject ELeitwegDAO dao;
	@Inject UserManager um;
	protected AbstractLoginController() {
		
	}
	/**
	 * Initiate the DB-Interface
	 */
	/*protected void initDAO() {
		log.info("Initalizing DAO");
		ClassPathResource res = new ClassPathResource("beans.xml");
		xbf = new XmlBeanFactory(res);
		dao = (ELeitwegDAO) xbf.getBean("eleitwegDAO");

	}*/

	public synchronized SC login(String username, String md5passwd)
			throws AuthorisationException, RemoteException {
		log.info("Login request for user: " + username);
		boolean authorized = false;
		um.getUserById(184);
		List<User> users = dao.getUsers();
		for (User u : users) {
			log.debug("comparing: " + username + "=" + u.getUsername() + "; " + md5passwd + "=" + u.getPasswdhash());
			if (isAuthorised(username, md5passwd, u)) {
				authorized = true;
				break;
			}
		}

		if (authorized) {
			return getSC();
		} else {
			throw new AuthorisationException("Username and/or password wrong.");
		}
	}
	
	public User getMe(String username, String md5passwd) throws AuthorisationException {
		List<User> users = dao.getUsers();
		log.debug("getMe got:" + users.size());
		for (User u : users) {
			log.debug("comparing: " + username + "=" + u.getUsername() + "; " + md5passwd + "=" + u.getPasswdhash());
			if(u.getUsername().equalsIgnoreCase(username) && u.getPasswdhash().equals(md5passwd)) {
				return u;
			}
		}
		throw new AuthorisationException("bad username and/or password");
	}
	
	public void addClientHandle(ClientHandle ch) {
		clients.add(ch);
	}

	protected synchronized void logout(ClientHandle ch) {
		Iterator<ClientHandle> chIt = clients.iterator();
		while(chIt.hasNext()) {
			if(chIt.next().equals(ch)) {
				chIt.remove();
			}
		}

	}

}
